import { HttpClient, HttpEventType } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';

export interface DownloadProgress {
  progress: number;
  loaded: number;
  total?: number;
  status: 'started' | 'in-progress' | 'completed' | 'error';
}

@Injectable({
  providedIn: 'root'
})
export class DownloadService {
  constructor(private http: HttpClient) {}
  downloadFile(url: string, filename?: string): Observable<DownloadProgress> {
    const progressSubject = new Subject<DownloadProgress>();

    this.http
      .get(url, {
        responseType: 'blob',
        reportProgress: true,
        observe: 'events'
      })
      .subscribe({
        next: (event: any) => {
          switch (event.type) {
            case HttpEventType.Sent:
              progressSubject.next({
                progress: 0,
                loaded: 0,
                status: 'started'
              });
              break;

            case HttpEventType.DownloadProgress:
              const progress = event.total ? Math.round((100 * event.loaded) / event.total) : Math.round(event.loaded / 1024);

              progressSubject.next({
                progress: progress,
                loaded: event.loaded,
                total: event.total,
                status: 'in-progress'
              });
              break;

            case HttpEventType.Response:
              progressSubject.next({
                progress: 100,
                loaded: event.total || event.loaded,
                total: event.total || event.loaded,
                status: 'completed'
              });

              // 触发文件下载
              this.saveFile(event.body, filename || this.getFilenameFromUrl(url));
              progressSubject.complete();
              break;
          }
        },
        error: error => {
          progressSubject.next({
            progress: 0,
            loaded: 0,
            status: 'error'
          });
          progressSubject.error(error);
        }
      });

    return progressSubject.asObservable();
  }

  private saveFile(blob: Blob, filename: string) {
    const url = window.URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = filename;
    link.click();
    window.URL.revokeObjectURL(url);
  }

  private getFilenameFromUrl(url: string): string {
    return url.split('/').pop() || 'download';
  }
}
